package semant.first_pass;

import semant.Env;
import symbol.ClassInfo;
import symbol.MethodInfo;
import symbol.Symbol;
import symbol.VarInfo;
import syntaxtree.VarDecl;
import syntaxtree.VisitorAdapter;

public class LocalDeclHandler extends VisitorAdapter {

	private Env env;
	private MethodInfo method;
	private ClassInfo info;

	public LocalDeclHandler(Env e, ClassInfo i, MethodInfo m) {
		env = e;
		method = m;
		info = i;
	}

	public static void firstPass(Env e, ClassInfo i, MethodInfo m, VarDecl node) {
		LocalDeclHandler h = new LocalDeclHandler(e, i, m);
		node.accept(h);
	}

	@Override
	public void visit(VarDecl node) {
		Symbol name = Symbol.symbol(node.name.s);
		VarInfo v = new VarInfo(node.type, name);

		// insere o atributo na tabela de variavies locais do metodo
		if (!method.addLocal(v)) {
			VarInfo old = method.localsTable.get(name);

			if (old == null) {
				old = method.formalsTable.get(name);
			}

			env.err.Error(node.name, new Object[] {
					"Redeclaracao do variavel \'" + name + "\' "
							+ "no metodo: \'" + method.name + "\'"
							+ "da classe \'" + info.name + "\'.",
					"Declaracao anterior em: [" + old.type.line + ", "
							+ old.type.row + "]" });
		}
	}

}
